package com.cysyz.mylib.myfilter.impl;

import com.cysyz.mylib.myfilter.MyFilter;
import com.cysyz.mylib.myfilter.matcher.Matcher;

import java.util.Collection;
import java.util.Iterator;

/**
 * 过滤工具类
 * 传入includes和excludes的集合，通过matcher提供的匹配规则，当匹配时触发filterEvent的onMatch方法。
 * 具体规则
 * includes和excludes规则
 *  1.如果只传入了includes，那么当target集合的项目匹配时，触发onMatch。
 *  2.如果只传入excludes，那么当target集合中的项目不匹配时，触发onMatch。
 *  3.如果两个都传入，那么就使用规则1。
 */
public class SimpleMyFilter implements MyFilter {
    private Matcher matcher;
    private Collection includes;
    private Collection excludes;

    /**
     *
     * @param matcher 具体的匹配规则提供者
     * @param includes  要包含的项目的集合
     * @param excludes  要排除的项目的集合
     */
    public SimpleMyFilter(Matcher matcher, Collection includes, Collection excludes) {
        this.matcher = matcher;
        this.includes = includes;
        this.excludes = excludes;
    }

    public SimpleMyFilter(Collection includes, Collection excludes) {
        this.matcher = new Matcher() {
            @Override
            public boolean match(Object target, Object includeOrExcludeVal) {
                if (target.equals(includeOrExcludeVal)) {
                    return true;
                }
                return false;
            }
        };
        this.includes = includes;
        this.excludes = excludes;
    }

    public SimpleMyFilter(Matcher matcher, Collection includes) {
        this(matcher, includes, null);
    }

    public SimpleMyFilter(Collection includes) {

        this(new Matcher() {
            @Override
            public boolean match(Object target, Object includeOrExcludeVal) {
                if (target.equals(includeOrExcludeVal)) {
                    return true;
                }
                return false;
            }
        }, includes, null);
    }

    @Override
    public boolean filter(Object target) {
        return this.filter0(target);
    }

    private boolean filter0(Object target) {
        boolean needFiltered = true;
        if (includes != null && !includes.isEmpty() && (excludes == null || excludes.isEmpty()) || (includes != null && !includes.isEmpty() && excludes != null && excludes.isEmpty())) {
            boolean isFind = false;
            for (Iterator tIterator = includes.iterator();tIterator.hasNext(); ) {
                Object include =  tIterator.next();
                if (matcher.match(target, include)) {
                    isFind = true;
                    break;
                }
            }
            if (isFind) {
                needFiltered = true;
            } else {
                needFiltered = false;
            }
        } else if ((includes == null || includes.isEmpty())&& excludes != null && !excludes.isEmpty()) {
            boolean isFind = false;
            for (Iterator tIterator = excludes.iterator(); tIterator.hasNext(); ) {
                Object exclude =  tIterator.next();
                if (matcher.match(target, exclude)) {
                    isFind = true;
                    break;
                }
            }

            if (isFind) {
                needFiltered = false;
            } else {
                needFiltered = true;
            }
        }

        return needFiltered;
    }
}
